﻿
#define _CRT_SECURE_NO_WARNINGS

#define FMT_HEADER_ONLY
#define FMT_UNICODE 0
#include <fmt/core.h>
#include <fmt/ranges.h>

#include <functional>

#include <treehh/tree.hh>

template<class T>
static void print_tree(const tree<T>& t, typename tree<T>::iterator iNode, std::string prefix,
    const std::function<void(const char*)>& pr)
{
    if (iNode == nullptr)
    {
        pr(fmt::format("{}", *t.begin()).c_str());
        print_tree(t, t.begin(), "", pr);
        return;
    }

    typename tree<T>::sibling_iterator iChildren;
    for (iChildren = t.begin(iNode); iChildren != t.end(iNode); ++iChildren) {
        if (t.next_sibling(iChildren) == t.end(iNode)) {
            pr(fmt::format("{}└───{}", prefix.c_str(), *iChildren).c_str());
            //pr(fmt::format("{}+---{}", prefix.c_str(), *iChildren).c_str());
        }
        else {
            pr(fmt::format("{}├───{}", prefix.c_str(), *iChildren).c_str());
            //pr(fmt::format("{}|---{}", prefix.c_str(), *iChildren).c_str());
        }

        if (t.begin(iChildren) != nullptr)
        {
            if (t.next_sibling(iChildren) == t.end(iNode))
                print_tree(t, iChildren, prefix + "    ", pr);
            else {
                print_tree(t, iChildren, prefix + "│   ", pr);
                //print_tree(t, iChildren, prefix + "|   ", pr);
            }
        }
    }
}


int main()
{
    tree<std::string> t;

    t.set_head("one");
    auto top = t.begin();
    auto i2 = t.append_child(top, "two");
    auto i3 = t.append_child(top, "three");
    auto i4 = t.append_child(top, "four");

    auto i21 = t.append_child(i2, "apple");
    auto i22 = t.append_child(i2, "pear");
    auto i221 = t.append_child(i22, "aaa");
    t.append_child(i22, "bbb");

    t.append_child(i221, "123");

    t.append_child(i3, "banana");
    t.append_child(i3, "kiwi");

    t.append_child(i4, "i4-1111");
    t.append_child(i4, "i4-2222");
    

    int index = 0;
    print_tree(t, nullptr, "", [&](const char* s) {
        printf("%4d %s\n", index++, s);
        });
}

// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单

// 入门使用技巧: 
//   1. 使用解决方案资源管理器窗口添加/管理文件
//   2. 使用团队资源管理器窗口连接到源代码管理
//   3. 使用输出窗口查看生成输出和其他消息
//   4. 使用错误列表窗口查看错误
//   5. 转到“项目”>“添加新项”以创建新的代码文件，或转到“项目”>“添加现有项”以将现有代码文件添加到项目
//   6. 将来，若要再次打开此项目，请转到“文件”>“打开”>“项目”并选择 .sln 文件
